package com.cj.mvvmlib.base.activity

import android.annotation.SuppressLint
import android.app.Dialog
import android.content.Intent
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.os.CountDownTimer
import android.os.Handler
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.Window
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import android.widget.LinearLayout
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.lifecycle.ViewModelProvider
import com.cj.mvvmlib.R
import com.cj.mvvmlib.base.viewmodel.BaseViewModel
import com.cj.mvvmlib.databinding.LoadingDialogBinding
import com.cj.mvvmlib.ext.getVmClazz
import com.cj.mvvmlib.ext.view.TitleBarView
import com.cj.mvvmlib.util.AppManager
import com.cj.mvvmlib.util.MyCountDownTimer

/**
 *
 * 描述　: ViewModelActivity基类，把ViewModel注入进来了
 */
abstract class BaseVmActivity<VM : BaseViewModel> : AppCompatActivity() {

    /**
     * 是否需要使用DataBinding 供子类BaseVmDbActivity修改，用户请慎动
     */
    private var isUserDb = false
    var savedInstanceState: Bundle? = null
    lateinit var viewModel: VM
    private var loadingDialog: Dialog? = null
    private var titleBar: TitleBarView? = null
    private lateinit var layoutMain: LinearLayout
    private var countDownView: TextView? = null
    private var time = 0
    private var countDownTimeFinishCallback: ((Unit) -> Unit)? = null

    private var countDownTimer: MyCountDownTimer? = null
    abstract fun layoutId(): View

    abstract fun initView(savedInstanceState: Bundle?)
    abstract fun initData()
    abstract fun setListener()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        this.savedInstanceState = savedInstanceState
        AppManager.getAppManager()?.addActivity(this)
        if (useTitleBar()) {
            layoutMain = LinearLayout(this)
            layoutMain.orientation = LinearLayout.VERTICAL
            titleBar = TitleBarView(this)
            layoutMain.addView(titleBar,
                LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.WRAP_CONTENT)
            titleBar?.useElevation()
            titleBar?.setTitleBarLeftClick { onBackPressed() }
        }
        if (!isUserDb) {
            setContentView(layoutId())
        } else {
            initDataBind()
        }
        init(savedInstanceState)
        setTitleBarRightClick {
            val intent = Intent("UserActivity")
            intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
            startActivity(intent)
        }
    }

    private fun init(savedInstanceState: Bundle?) {
        viewModel = createViewModel()
        registerUiChange()
        initData()
        initView(savedInstanceState)
        setListener()
        createObserver()
    }

    override fun setContentView(view: View) {
        if (useTitleBar()) {
            layoutMain.addView(view,
                LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.MATCH_PARENT)
            super.setContentView(layoutMain)
        } else {
            super.setContentView(view)
        }
    }

    /**
     * 创建viewModel
     */
    private fun createViewModel(): VM {
        return ViewModelProvider(this).get(getVmClazz(this))
    }

    /**
     * 创建LiveData数据观察者
     */
    abstract fun createObserver()

    /**
     * 注册UI 事件
     */
    private fun registerUiChange() { //显示弹窗
        viewModel.loadingChange.showDialog.observe(this) {
            showLoadingDialog(it)
        } //关闭弹窗
        viewModel.loadingChange.dismissDialog.observe(this) {
            dismissLoadingDialog()
        }
    }

    /**
     * 将非该Activity绑定的ViewModel添加 loading回调 防止出现请求时不显示 loading 弹窗bug
     * @param viewModels Array<out BaseViewModel>
     */
    protected fun addLoadingObserve(vararg viewModels: BaseViewModel) {
        viewModels.forEach { viewModel -> //显示弹窗
            viewModel.loadingChange.showDialog.observe(this) {} //关闭弹窗
            viewModel.loadingChange.dismissDialog.observe(this) {}
        }
    }

    fun userDataBinding(isUserDb: Boolean) {
        this.isUserDb = isUserDb
    }

    /**
     * 供子类BaseVmDbActivity 初始化Databinding操作
     */
    open fun initDataBind() {

    }


    protected open fun useTitleBar() = true


    protected fun setTitleBarBackground(id: Int) = titleBar?.setBackgroundColor(id)

    protected fun getTitleBarRight() = titleBar?.getRightText()

    protected fun getTitleBarLeft() = titleBar?.getLeftText()

    protected fun setTitleBarText(title: String?) = titleBar?.setTitleBarText(title)

    protected fun setTitleBarText(id: Int) = titleBar?.setTitleBarText(resources.getString(id))

    protected fun setTitleBarRightColor(color: Int) =
        titleBar?.setTitleBarRightColor(ContextCompat.getColor(this, color))

    protected fun setTitleBarColor(color: Int) =
        titleBar?.setTitleBarColor(ContextCompat.getColor(this, color))

    protected fun setTitleBarLeft(drawable: Int) = titleBar?.setLeftDrawable(drawable)

    protected fun setTitleBarRight(drawable: Int) = titleBar?.setRightDrawable(drawable)

    protected fun setTitleBarLeft(leftText: String) = titleBar?.setLeftText(leftText)

    protected fun setTitleBarRight(rightText: String) = titleBar?.setRightText(rightText)

    protected fun setTitleBarRight(rightText: String, iconId: Int, iconAtLeft: Boolean = true) =
        titleBar?.setRightTextAndIcon(rightText, iconId, iconAtLeft)

    protected fun setTitleBarLeft(leftText: String, iconId: Int, iconAtLeft: Boolean = true) =
        titleBar?.setLeftTextAndIcon(leftText, iconId, iconAtLeft)

    protected fun setTitleBarLeftVisibility(visibility: Int) =
        titleBar?.setLeftVisibility(visibility)

    protected fun setTitleBarRightVisibility(visibility: Int) =
        titleBar?.setRightVisibility(visibility)

    protected fun setTitleBarVisibility(visibility: Int) = { titleBar?.visibility = visibility }()

    protected fun setTitleBarRightClick(func: () -> Unit) =
        titleBar?.setTitleBarRightClick { func() }

    protected fun setTitleBarLeftClick(func: () -> Unit) = titleBar?.setTitleBarLeftClick { func() }

    protected fun setTitleBarTitleClick(click: () -> Unit) =
        titleBar?.setTitleBarTitleClick { click() }

    protected fun getTitleBar() = titleBar

    @SuppressLint("InflateParams")
    open fun showLoadingDialog(text: String = getString(R.string.loading)) {
        val dialogBinding = LoadingDialogBinding.inflate(layoutInflater)
        if (loadingDialog == null) {
            loadingDialog = Dialog(this)
            loadingDialog?.let {
                it.setCanceledOnTouchOutside(false)
                dialogBinding.titleTv.text = text
                it.requestWindowFeature(Window.FEATURE_NO_TITLE) // 设置对话框无标题
                it.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) // 设置对话框背景透明
                it.setContentView(dialogBinding.root)
                it.show()
            }
        } else {
            dialogBinding.titleTv.text = text
            loadingDialog?.setContentView(dialogBinding.root)
            loadingDialog?.show()
        }
    }

    open fun dismissLoadingDialog() {
        loadingDialog?.let {
            if (it.isShowing) {
                it.dismiss()
            }
        }
    }

    override fun dispatchTouchEvent(event: MotionEvent?): Boolean {
        countDownTimer?.cancel()
        countDownTimer = null
        countDownView?.text = ""
        countDownTimerHandler.removeCallbacks(countDownTimerRunnable)
        countDownTimerHandler.postDelayed(countDownTimerRunnable, 2000)
        if (event?.action == MotionEvent.ACTION_DOWN) { // 获得当前得到焦点的View，一般情况下就是EditText（特殊情况就是轨迹求或者实体案件会移动焦点）
            val v = currentFocus
            if (isShouldHideInput(v, event)) {
                val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
                imm.hideSoftInputFromWindow(v!!.windowToken, 0)
            }
        }
        return super.dispatchTouchEvent(event)
    }

    /**
     * 根据EditText所在坐标和用户点击的坐标相对比，来判断是否隐藏键盘，因为当用户点击EditText时没必要隐藏
     *
     * @param v
     * @param event
     * @return
     */
    private fun isShouldHideInput(v: View?, event: MotionEvent): Boolean {
        if (v != null && v is EditText) {
            val l = intArrayOf(0, 0)
            v.getLocationInWindow(l)
            val left = l[0]
            val top = l[1]
            val bottom = top + v.getHeight()
            val right = (left + v.getWidth())
            return !(event.x > left && event.x < right && event.y > top && event.y < bottom)
        } // 如果焦点不是EditText则忽略，这个发生在视图刚绘制完，第一个焦点不在EditView上，和用户用轨迹球选择其他的焦点
        return false
    }

    /**
     * 开始倒计时
     * @param countDownView 倒计时view
     * @param time 倒计时时间（秒）
     */
    open fun startCountDownTimer(countDownView: TextView?,
        time: Int,
        finishCallback: (Unit) -> Unit) {
        this.countDownTimeFinishCallback = finishCallback
        this.countDownView = countDownView
        this.time = time
        countDownTimer?.cancel()
        countDownTimer = null
        countDownView?.let {
            countDownTimer = MyCountDownTimer(time * 1000L, 1000, countDownView) {
                finishCallback.invoke(Unit)
                countDownTimer = null
            }
            countDownTimer?.start()
        }
    }

    /**
     * 取消倒计时
     */
    open fun cancelCountDownTimer() {
        countDownTimer?.cancel()
        countDownTimer = null
    }

    /*  //重写字体缩放比例 api<25
                      override fun getResources(): Resources {
                          val res = super.getResources()
                          if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.N) {
                              val config = res.configuration
                              config.fontScale = BaseApp.getFontScale() //1 设置正常字体大小的倍数
                              res.updateConfiguration(config, res.displayMetrics)
                          }
                          return res
                      }

                      //重写字体缩放比例  api>25
                      override fun attachBaseContext(newBase: Context) {
                          if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) {
                              val res = newBase.resources
                              val config = res.configuration
                              config.fontScale = BaseApp.getFontScale() //1 设置正常字体大小的倍数
                              val newContext = newBase.createConfigurationContext(config)
                              super.attachBaseContext(newContext)
                          } else {
                              super.attachBaseContext(newBase)
                          }
                      }*/
    override fun onDestroy() {
        super.onDestroy()
        countDownTimer?.cancel()
        countDownTimer = null
    }

    private val countDownTimerHandler = Handler()
    private val countDownTimerRunnable: Runnable = Runnable {
        countDownView?.let {
            countDownTimer = MyCountDownTimer(time * 1000L, 1000, it) {
                countDownTimer = null
                countDownTimeFinishCallback?.invoke(Unit)
            }
            countDownTimer?.start()
        }
    }
}